package org.ruoyi.interview.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import org.ruoyi.interview.domain.InterviewQuestionCategory;
import org.ruoyi.interview.domain.vo.InterviewQuestionCategoryVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.ruoyi.common.core.utils.MapstructUtils;
import org.ruoyi.common.core.utils.StringUtils;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.interview.domain.InterviewQuestion;
import org.ruoyi.interview.domain.InterviewQuestionFieldRelation;
import org.ruoyi.interview.domain.InterviewQuestionTagRelation;
import org.ruoyi.interview.domain.bo.InterviewQuestionBo;
import org.ruoyi.interview.domain.vo.InterviewQuestionVo;
import org.ruoyi.interview.mapper.InterviewQuestionFieldRelationMapper;
import org.ruoyi.interview.mapper.InterviewQuestionMapper;
import org.ruoyi.interview.mapper.InterviewQuestionTagRelationMapper;
import org.ruoyi.interview.mapper.InterviewQuestionCategoryMapper;
import org.ruoyi.interview.service.IInterviewQuestionService;

import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 面试题Service业务层处理
 *
 * @author ruoyi
 */
@Service
@RequiredArgsConstructor
public class InterviewQuestionServiceImpl implements IInterviewQuestionService {

    private final InterviewQuestionMapper baseMapper;
    private final InterviewQuestionFieldRelationMapper fieldRelationMapper;
    private final InterviewQuestionTagRelationMapper tagRelationMapper;
    private final InterviewQuestionCategoryMapper categoryMapper;

    /**
     * 查询面试题
     *
     * @param questionId 面试题主键
     * @return 面试题
     */
    @Override
    public InterviewQuestionVo selectInterviewQuestionById(Long questionId) {
        InterviewQuestionVo vo = baseMapper.selectVoById(questionId);
        if (vo != null) {
            // 查询关联的领域
            List<InterviewQuestionFieldRelation> fieldRelations = fieldRelationMapper.selectList(
                new LambdaQueryWrapper<InterviewQuestionFieldRelation>()
                    .eq(InterviewQuestionFieldRelation::getQuestionId, questionId)
            );
            List<Long> fieldIds = fieldRelations.stream()
                .map(InterviewQuestionFieldRelation::getFieldId)
                .collect(Collectors.toList());
            vo.setFieldIds(fieldIds);

            // 查询关联的标签
            List<InterviewQuestionTagRelation> tagRelations = tagRelationMapper.selectList(
                new LambdaQueryWrapper<InterviewQuestionTagRelation>()
                    .eq(InterviewQuestionTagRelation::getQuestionId, questionId)
            );
            List<Long> tagIds = tagRelations.stream()
                .map(InterviewQuestionTagRelation::getTagId)
                .collect(Collectors.toList());
            vo.setTagIds(tagIds);
        }
        return vo;
    }

    /**
     * 查询面试题列表
     *
     * @param bo 面试题业务对象
     * @return 面试题集合
     */
    @Override
    public List<InterviewQuestionVo> selectInterviewQuestionList(InterviewQuestionBo bo) {
        LambdaQueryWrapper<InterviewQuestion> lqw = buildQueryWrapper(bo);
        lqw.eq(InterviewQuestion::getDelFlag, "0");
        return baseMapper.selectVoList(bo);
    }

    /**
     * 查询面试题列表
     *
     * @param bo 面试题业务对象
     * @param pageQuery 分页对象
     * @return 面试题集合
     */
    @Override
    public TableDataInfo<InterviewQuestionVo> selectInterviewQuestionList(InterviewQuestionBo bo, PageQuery pageQuery) {

        if (ObjectUtil.isNotEmpty(bo.getParentId())){
            // 根据parentId查询子分类
            List<InterviewQuestionCategory> categories = categoryMapper.selectListByParentId(bo.getParentId());

            if (categories != null && !categories.isEmpty()) {
                // 提取子分类ID列表
                List<Long> categoryIds = categories.stream()
                    .map(InterviewQuestionCategory::getCategoryId)
                    .collect(Collectors.toList());

                // 构建查询条件
                LambdaQueryWrapper<InterviewQuestion> lqw = buildQueryWrapper(bo);
                lqw.eq(InterviewQuestion::getDelFlag, "0");
                lqw.in(InterviewQuestion::getCategoryId, categoryIds);

                IPage<InterviewQuestionVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
                return TableDataInfo.build(result);
            } else {
                // 如果没有子分类，返回空结果
                IPage<InterviewQuestionVo> result = new Page<>(pageQuery.getPageNum(), pageQuery.getPageSize());
                return TableDataInfo.build(result);
            }
        }else{
            LambdaQueryWrapper<InterviewQuestion> lqw = buildQueryWrapper(bo);
            lqw.eq(InterviewQuestion::getDelFlag, "0");
            IPage<InterviewQuestionVo> result = baseMapper.selectVoPageWithCategory(bo, pageQuery.build());
            return TableDataInfo.build(result);
        }
    }

    /**
     * 根据父级分类ID查询面试题列表（连表查询）
     *
     * @param bo 面试题业务对象
     * @param pageQuery 分页对象
     * @return 面试题集合
     */
    @Override
    public TableDataInfo<InterviewQuestionVo> selectInterviewQuestionListByParentId(InterviewQuestionBo bo, PageQuery pageQuery) {
        Page<InterviewQuestionVo> page = baseMapper.selectVoPageByParentId(bo, pageQuery.build());
        return TableDataInfo.build(page);
    }

    /**
     * 查询面试题列表(带收藏状态)
     *
     * @param bo 面试题业务对象
     * @param pageQuery 分页对象
     * @param userId 用户ID
     * @return 面试题集合
     */
    @Override
    public TableDataInfo<InterviewQuestionVo> selectInterviewQuestionListWithFavorite(InterviewQuestionBo bo, PageQuery pageQuery, Long userId) {
        LambdaQueryWrapper<InterviewQuestion> lqw = buildQueryWrapper(bo);
        lqw.eq(InterviewQuestion::getDelFlag, "0");
        IPage<InterviewQuestionVo> result = baseMapper.selectVoPageWithFavorite(bo, pageQuery.build(), userId);
        return TableDataInfo.build(result);
    }

    /**
     * 查询面试题列表(带收藏状态和掌握状态)
     *
     * @param bo 面试题业务对象
     * @param pageQuery 分页对象
     * @param userId 用户ID
     * @return 面试题集合
     */
    @Override
    public TableDataInfo<InterviewQuestionVo> selectInterviewQuestionListWithStatus(InterviewQuestionBo bo, PageQuery pageQuery, Long userId) {
        LambdaQueryWrapper<InterviewQuestion> lqw = buildQueryWrapper(bo);
        lqw.eq(InterviewQuestion::getDelFlag, "0");
        IPage<InterviewQuestionVo> result = baseMapper.selectVoPageWithStatus(bo, pageQuery.build(), userId);
        return TableDataInfo.build(result);
    }

    /**
     * 查询用户收藏的面试题列表
     *
     * @param userId 用户ID
     * @param categoryId 分类ID
     * @param bo 面试题业务对象
     * @param pageQuery 分页对象
     * @return 面试题集合
     */
    @Override
    public TableDataInfo<InterviewQuestionVo> selectFavoriteQuestionList(Long userId, Long categoryId, InterviewQuestionBo bo, PageQuery pageQuery) {
        Page<InterviewQuestionVo> page = new Page<>(pageQuery.getPageNum(), pageQuery.getPageSize());
        Page<InterviewQuestionVo> result = baseMapper.selectFavoriteQuestionVoList(userId, categoryId, bo, page);
        return TableDataInfo.build(result);
    }

    /**
     * 新增面试题
     *
     * @param bo 面试题业务对象
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean insertInterviewQuestion(InterviewQuestionBo bo) {
        InterviewQuestion add = MapstructUtils.convert(bo, InterviewQuestion.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setQuestionId(add.getQuestionId());
            // 保存关联的领域
            saveFieldRelations(add.getQuestionId(), bo.getFieldIds());
            // 保存关联的标签
            saveTagRelations(add.getQuestionId(), bo.getTagIds());
        }
        return flag;
    }

    /**
     * 修改面试题
     *
     * @param bo 面试题业务对象
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateInterviewQuestion(InterviewQuestionBo bo) {
        InterviewQuestion update = MapstructUtils.convert(bo, InterviewQuestion.class);
        validEntityBeforeSave(update);
        boolean flag = baseMapper.updateById(update) > 0;
        if (flag) {
            // 先删除原有的关联关系
            fieldRelationMapper.delete(
                new LambdaQueryWrapper<InterviewQuestionFieldRelation>()
                    .eq(InterviewQuestionFieldRelation::getQuestionId, bo.getQuestionId())
            );
            tagRelationMapper.delete(
                new LambdaQueryWrapper<InterviewQuestionTagRelation>()
                    .eq(InterviewQuestionTagRelation::getQuestionId, bo.getQuestionId())
            );
            // 重新保存关联的领域
            saveFieldRelations(bo.getQuestionId(), bo.getFieldIds());
            // 重新保存关联的标签
            saveTagRelations(bo.getQuestionId(), bo.getTagIds());
        }
        return flag;
    }

    /**
     * 修改面试题状态
     *
     * @param questionId 面试题主键
     * @param status 状态值
     * @return 结果
     */
    @Override
    public Boolean updateQuestionStatus(Long questionId, String status) {
        return baseMapper.update(null,
            new UpdateWrapper<InterviewQuestion>()
                .set("status", status)
                .eq("question_id", questionId)) > 0;
    }

    /**
     * 批量删除面试题
     *
     * @param questionIds 需要删除的面试题主键集合
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteInterviewQuestionByIds(Collection<Long> questionIds) {
        for (Long questionId : questionIds) {
            UpdateWrapper<InterviewQuestion> interviewQuestionUpdateWrapper = new UpdateWrapper<>();
            interviewQuestionUpdateWrapper.set("del_flag", "2");
            interviewQuestionUpdateWrapper.eq("question_id", questionId);
            baseMapper.update(interviewQuestionUpdateWrapper);
        }
        return true;
    }

    /**
     * 批量新增面试题
     *
     * @param boList 面试题业务对象列表
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean insertInterviewQuestions(List<InterviewQuestionBo> boList) {
        for (InterviewQuestionBo bo : boList) {
            InterviewQuestion add = MapstructUtils.convert(bo, InterviewQuestion.class);
            validEntityBeforeSave(add);
            boolean flag = baseMapper.insert(add) > 0;
            if (flag) {
                bo.setQuestionId(add.getQuestionId());
                // 保存关联的领域
                saveFieldRelations(add.getQuestionId(), bo.getFieldIds());
                // 保存关联的标签
                saveTagRelations(add.getQuestionId(), bo.getTagIds());
            }
        }
        return true;
    }

    /**
     * 保存面试题关联的领域
     */
    private void saveFieldRelations(Long questionId, List<Long> fieldIds) {
        if (fieldIds != null && !fieldIds.isEmpty()) {
            for (Long fieldId : fieldIds) {
                InterviewQuestionFieldRelation relation = new InterviewQuestionFieldRelation();
                relation.setQuestionId(questionId);
                relation.setFieldId(fieldId);
                fieldRelationMapper.insert(relation);
            }
        }
    }

    /**
     * 保存面试题关联的标签
     */
    private void saveTagRelations(Long questionId, List<Long> tagIds) {
        if (tagIds != null && !tagIds.isEmpty()) {
            for (Long tagId : tagIds) {
                InterviewQuestionTagRelation relation = new InterviewQuestionTagRelation();
                relation.setQuestionId(questionId);
                relation.setTagId(tagId);
                tagRelationMapper.insert(relation);
            }
        }
    }

    /**
     * 构建查询条件
     */
    private LambdaQueryWrapper<InterviewQuestion> buildQueryWrapper(InterviewQuestionBo bo) {
        LambdaQueryWrapper<InterviewQuestion> lqw = Wrappers.lambdaQuery();
        lqw.like(StringUtils.isNotBlank(bo.getContent()), InterviewQuestion::getContent, bo.getContent());
        lqw.eq(StringUtils.isNotBlank(bo.getType()), InterviewQuestion::getType, bo.getType());
        lqw.eq(StringUtils.isNotBlank(bo.getDifficulty()), InterviewQuestion::getDifficulty, bo.getDifficulty());
        lqw.eq(bo.getCategoryId() != null, InterviewQuestion::getCategoryId, bo.getCategoryId());
        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), InterviewQuestion::getStatus, bo.getStatus());
        lqw.eq(StringUtils.isNotBlank(bo.getIsHot()), InterviewQuestion::getIsHot, bo.getIsHot());
        return lqw;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(InterviewQuestion entity) {
        // TODO 做一些数据校验,如唯一约束
    }
}
